import { memo, useCallback, useEffect, useState } from 'react';
import { Position, useReactFlow, Node } from '@xyflow/react';
import { Card, Form, Input, InputNumber, Modal, Slider, Spin } from 'antd';
import Subtitle from '../../components/Subtitle';
import useSelectBorder from '../../store/useSceneData';
import CustomHandle from '../CustomHandle';
import CustomSelect from '../../components/CustomSelect';
import { Loading3QuartersOutlined } from '@ant-design/icons';
import NodeOperation from '../../components/NodeOperation';
import LlmSelect from '../../components/LlmSelect';
import { useRequest } from 'ahooks';
import { nodeRun } from '@/api/request';
import useInitVariable from '@/hooks/useInitVariable';


const layout = {
  labelCol: { span: 10 },
  wrapperCol: { span: 12 },
};

/**
 * 知识库节点
 * @param param0 
 * @returns 
 */
function KnowledgeNode({ id, data }: Node) {
  const [text, setText] = useState(data.document);
  const { setNodes, setCenter, getNodes } = useReactFlow();
  const { select, setSelectId, debug, setDeBug } = useSelectBorder()
  const [isModalOpen, setIsModalOpen] = useState(false)
  const [isRun, setIsRun] = useState(false)
  const [form] = Form.useForm();
  const [runForm] = Form.useForm();
  const [knowledge, setKnowledge] = useState("")
  const { initSetVariable } = useInitVariable()

  const { run, loading } = useRequest(nodeRun, {
    manual: true,
    onSuccess: (result) => {
      setKnowledge(result.data)
    }
  });

  const handleFocus = () => {
    setSelectId(id);
    setDeBug(false)
  };

  const onChange = useCallback((value: string) => {
    setNodes((nodes) => {
      const node = nodes.find(node => node.id == id)
      node.data.document = value
      return [...nodes];
    })
    setText(value);
  }, []);

  useEffect(() => {
    if (select[id] && debug) {
      setNodes((nodes) => {
        const node = nodes.find(node => node.id == id)
        setCenter(node.position.x + 200, node.position.y, { zoom: 1, duration: 500 })
        return [...nodes];
      })
    }
  }, [select[id]])

  useEffect(() => {
    initSetVariable(data.title as string || "知识库", id)
  }, [])

  return (
    <NodeOperation nodeId={id}
      onClick={() => (setIsModalOpen(true),
        form.setFieldsValue({ llmParam: data.llmParam || 'sys.query', knowledgeNum: data.knowledgeNum || 3, rankerNum: data.rankerNum || 2, rankerThreshold: data.rankerThreshold || 0.01 }))}
      onClickRun={() => (setIsRun(true), setKnowledge(""), form.resetFields())}
      showRun={true}>
      <Card title={<div className='flex'>
        <Subtitle imgUrl='img/book.png' title={data.title as string || '知识库'} id={id} onBlur={(title) => initSetVariable(title, id)} />
        {select[id] && debug && <Spin indicator={<Loading3QuartersOutlined spin />} className='mt-[6px] ml-2' />}
      </div>}
        style={{
          outline: select[id] ? "2px solid #145FF0" : "none",
          width: 310,
        }}
        onClick={handleFocus}
        tabIndex={0}
      >
        <CustomHandle
          type="target"
          position={Position.Left}
          id="knowledgeStart"
          style={{ top: 74 }}
          count={2} />
        <CustomSelect
          value={text}
          showSearch
          mode="multiple"
          style={{ minWidth: 258, maxWidth: 280 }}
          placeholder="请选择知识库"
          optionFilterProp="label"
          onChange={onChange}
          className="nodrag"
        />
        <CustomHandle
          type="source"
          position={Position.Right}
          style={{ top: 74 }}
          count={1}
          id="knowledgeEnd" />
      </Card>

      <Modal title={<span>{data.title as string || '检索参数'}</span>}
        open={isModalOpen}
        destroyOnClose={true}
        footer={false}
        onCancel={() => {
          setNodes((nodes) => {
            const node = nodes.find(node => node.id == id)
            node.data.llmParam = form.getFieldValue('llmParam')
            node.data.knowledgeNum = form.getFieldValue('knowledgeNum')
            node.data.rankerNum = form.getFieldValue('rankerNum')
            node.data.rankerThreshold = form.getFieldValue('rankerThreshold')
            return [...nodes];
          })
          setIsModalOpen(false)
        }}>
        <Form className='mt-4' form={form}  {...layout}>
          <Form.Item name="llmParam" className='w-full' label="检索值">
            <LlmSelect />
          </Form.Item >
          <Form.Item name="knowledgeNum" className='w-full' label="Embedding返回条数" tooltip="通过知识库检索获取最前面的条数，做为知识参考">
            <Slider min={1} max={10} />
          </Form.Item>
          <Form.Item name="rankerNum" className='w-full' label="Reranker返回条数" tooltip="获取Embedding返回条数进行排序，根据你设置的值，返回排序最靠前面的条数">
            <Slider min={1} max={10} />
          </Form.Item>
          <Form.Item name="rankerThreshold" className='w-full' label="Reranker阈值" tooltip="会对返回的条数做排序，只有大于所设置的阈值才会被保留，阀值越高需要相似度越高">
            <InputNumber max={1} step={0.01}/>
          </Form.Item>
        </Form>
      </Modal>

      <Modal title="执行"
        open={isRun}
        okText="查询"
        onCancel={() => setIsRun(false)}
        onOk={() =>
          run({ query: runForm.getFieldValue('query'), variable: {}, nodeData: JSON.stringify(getNodes().filter((e) => e.id == id)), type: "knowledgeNode" })
        }
        confirmLoading={loading}
        onClose={() => setIsRun(false)}>
        <Form className='flex mt-4' form={runForm}>
          <Form.Item name="query" className='w-full'>
            <Input autoComplete="off" placeholder='知识库查询' />
          </Form.Item>
        </Form>
        {knowledge && <div className='w-full max-h-[300px] overflow-auto whitespace-pre-wrap break-words bg-[#F3F4F7] rounded-lg p-2'>
          {knowledge}
        </div>}
      </Modal>

    </NodeOperation>
  );
}

export default memo(KnowledgeNode);